package com.zrkizzy.module.scheduler.utils;

import com.zrkizzy.common.core.constant.DateTimeConst;
import com.zrkizzy.module.scheduler.exception.SchedulerErrorCode;
import org.quartz.CronExpression;

import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;

/**
 * Cron表达式工具类
 *
 * @author zhangrongkang
 * @since 2024/3/4
 */
public class CronUtil {

    /**
     * 校验cron表达式
     *
     * @param cron cron表达式
     */
    public static void validCronExpression(String cron) {
        if (!CronExpression.isValidExpression(cron)) {
            throw SchedulerErrorCode.CRON_EXPRESSION_ERROR.exception();
        }
    }

    /**
     * 校验cron是否已过期
     *
     * @param cron cron表达式
     * @return true--过期，false--未过期
     */
    public static boolean validCronExpire(String cron) {
        Date execution = getNextExecution(cron);
        // 如果没有下一次执行时间说明过期
        if (Objects.isNull(execution)) {
            return true;
        }
        return new Date().after(execution);
    }

    /**
     * 返回下一个执行时间根据给定的Cron表达式
     *
     * @param cron Cron表达式
     * @return Date 下次Cron表达式执行时间
     */
    public static Date getNextExecution(String cron) {
        try {
            CronExpression cronExpression = new CronExpression(cron);
            return cronExpression.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
        } catch (ParseException e) {
            throw SchedulerErrorCode.CRON_EXPRESSION_ERROR.exception();
        }
    }

    /**
     * 转换时间为Cron表达式
     *
     * @param time 定时任务执行时间，例如：2024-03-16 23:37:55
     * @return Cron表达式
     */
    public static String convertTimeToCron(String time) {
        // 格式化时间为LocalDateTime类型
        LocalDateTime localDateTime = LocalDateTime.parse(time, DateTimeFormatter.ofPattern(DateTimeConst.DATE_TIME_FORMAT));
        // 将LocalDateTime时间类型转为Cron表达式
        String cron = localDateTime.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));
        System.out.println("校验的cron：" + cron);
        // 校验转换出的Cron表达式是否有效
        if (validCronExpire(cron)) {
            throw SchedulerErrorCode.CRON_EXPRESSION_ERROR.exception();
        }
        return cron;
    }

}
